From: Carlhuda Date: Sat, 19 Apr 2014 00:23:07 +0000 (-0700) Subject: Restructure and progress towards simple compile X-Git-Tag: archive/raspbian/0.35.0-2+rpi1~3^2^2^2^2^2^2^2~1113 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=62bff631e920149b16336d1088f6c032d845969e;p=cargo.git Restructure and progress towards simple compile For now, we're going to use the operations as a library. We have some work to do before they can transparently be used as commands, but we're keeping an eye on making sure they remain conceptually usable over the shell. --- diff --git a/src/bin/cargo-compile.rs b/src/bin/cargo-compile.rs index 91f535639..9fa581a3e 100644 --- a/src/bin/cargo-compile.rs +++ b/src/bin/cargo-compile.rs @@ -1,26 +1,9 @@ #![crate_id="cargo-compile"] #![allow(deprecated_owned_vector)] -extern crate serialize; -extern crate hammer; extern crate cargo; -use std::vec::Vec; -use serialize::{Decodable}; -use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError}; -use std::io; -use std::io::BufReader; -use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig}; -use cargo::{ToCargoError,CargoResult}; - -#[deriving(Decodable)] -struct Options { - manifest_path: ~str -} - -impl FlagConfig for Options { - fn config(_: Option, c: FlagConfiguration) -> FlagConfiguration { c } -} +use cargo::ops::cargo_compile::compile; fn main() { match compile() { @@ -28,51 +11,3 @@ fn main() { Ok(_) => return } } - -fn compile() -> CargoResult<()> { - let options = try!(flags::()); - let manifest_bytes = try!(read_manifest(options.manifest_path).to_cargo_error(~"Could not read manifest", 1)); - - call_rustc(~BufReader::new(manifest_bytes.as_slice())) -} - -fn flags>() -> CargoResult { - let mut decoder = FlagDecoder::new::(std::os::args().tail()); - Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1) -} - -fn read_manifest(manifest_path: &str) -> CargoResult> { - Ok((try!(exec_with_output("cargo-read-manifest", [~"--manifest-path", manifest_path.to_owned()], None))).output) -} - -fn call_rustc(mut manifest_data: ~Reader:) -> CargoResult<()> { - let data: &mut Reader = manifest_data; - try!(exec_tty("cargo-rustc", [], Some(data))); - Ok(()) -} - -fn exec_with_output(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult { - Ok((try!(exec(program, args, input, |_| {}))).wait_with_output()) -} - -fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult { - Ok((try!(exec(program, args, input, |config| { - config.stdout = InheritFd(1); - config.stderr = InheritFd(2); - }))).wait()) -} - -fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult { - let mut config = ProcessConfig::new(); - config.program = program; - config.args = args; - configurator(&mut config); - - println!("Executing {} {}", program, args); - - let mut process = try!(Process::configure(config).to_cargo_error(~"Could not configure process", 1)); - - input.map(|mut reader| io::util::copy(&mut reader, process.stdin.get_mut_ref())); - - Ok(process) -} diff --git a/src/bin/cargo-read-manifest.rs b/src/bin/cargo-read-manifest.rs index ca404afb2..54ca728fb 100644 --- a/src/bin/cargo-read-manifest.rs +++ b/src/bin/cargo-read-manifest.rs @@ -2,87 +2,10 @@ #![allow(deprecated_owned_vector)] extern crate cargo; -extern crate hammer; -extern crate serialize; -extern crate toml; -use hammer::FlagConfig; -use serialize::Decoder; -use toml::from_toml; -use cargo::core; -use cargo::{CargoResult,ToCargoError,execute_main_without_stdin}; -use std::path::Path; - -#[deriving(Decodable,Encodable,Eq,Clone,Ord)] -struct SerializedManifest { - project: ~core::Project, - lib: Option<~[SerializedLibTarget]>, - bin: Option<~[SerializedExecTarget]> -} - -#[deriving(Decodable,Encodable,Eq,Clone,Ord)] -pub struct SerializedTarget { - name: ~str, - path: Option<~str> -} - -pub type SerializedLibTarget = SerializedTarget; -pub type SerializedExecTarget = SerializedTarget; - - -#[deriving(Decodable,Eq,Clone,Ord)] -struct ReadManifestFlags { - manifest_path: ~str -} - -impl FlagConfig for ReadManifestFlags {} +use cargo::execute_main_without_stdin; +use cargo::ops::cargo_read_manifest::execute; fn main() { execute_main_without_stdin(execute); } - -fn execute(flags: ReadManifestFlags) -> CargoResult> { - let manifest_path = flags.manifest_path; - let root = try!(toml::parse_from_file(manifest_path.clone()).to_cargo_error(format!("Couldn't parse Toml file: {}", manifest_path), 1)); - - let toml_manifest = try!(from_toml::(root.clone()).to_cargo_error(|e: toml::Error| format!("{}", e), 1)); - - let (lib, bin) = normalize(&toml_manifest.lib, &toml_manifest.bin); - - Ok(Some(core::Manifest { - root: try!(Path::new(manifest_path.clone()).dirname_str().to_cargo_error(format!("Could not get dirname from {}", manifest_path), 1)).to_owned(), - project: toml_manifest.project, - lib: lib, - bin: bin - })) -} - -fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> (~[core::LibTarget], ~[core::ExecTarget]) { - fn lib_targets(libs: &[SerializedLibTarget]) -> ~[core::LibTarget] { - let l = &libs[0]; - let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name)); - ~[core::LibTarget { path: path, name: l.name.clone() }] - } - - fn bin_targets(bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) -> ~[core::ExecTarget] { - bins.iter().map(|bin| { - let path = bin.path.clone().unwrap_or_else(|| default(bin)); - core::ExecTarget { path: path, name: bin.name.clone() } - }).collect() - } - - match (lib, bin) { - (&Some(ref libs), &Some(ref bins)) => { - (lib_targets(libs.as_slice()), bin_targets(bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name))) - }, - (&Some(ref libs), &None) => { - (lib_targets(libs.as_slice()), ~[]) - }, - (&None, &Some(ref bins)) => { - (~[], bin_targets(bins.as_slice(), |bin| format!("src/{}.rs", bin.name))) - }, - (&None, &None) => { - (~[], ~[]) - } - } -} diff --git a/src/bin/cargo-rustc.rs b/src/bin/cargo-rustc.rs index 7f4304a49..46977b3f8 100644 --- a/src/bin/cargo-rustc.rs +++ b/src/bin/cargo-rustc.rs @@ -1,72 +1,11 @@ #![crate_id="cargo-rustc"] #![allow(deprecated_owned_vector)] -extern crate toml; -extern crate hammer; -extern crate serialize; extern crate cargo; -use std::os::args; -use std::io; -use std::io::process::{Process,ProcessConfig,InheritFd}; -use std::path::Path; -use cargo::{CargoResult,CargoError,ToCargoError,NoFlags,execute_main}; -use cargo::core; - -/** - cargo-rustc -- ...args - - Delegate ...args to actual rustc command -*/ +use cargo::execute_main; +use cargo::ops::cargo_rustc::execute; fn main() { execute_main(execute); } - -fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult> { - let core::Manifest { root, lib, bin, .. } = manifest; - - let (crate_type, out_dir) = if lib.len() > 0 { - ( ~"lib", lib[0].path ) - } else if bin.len() > 0 { - ( ~"bin", bin[0].path ) - } else { - return Err(CargoError::new(~"bad manifest, no lib or bin specified", 1)); - }; - - let root = Path::new(root); - let target = join(&root, ~"target"); - - let args = [ - join(&root, out_dir), - ~"--out-dir", target, - ~"--crate-type", crate_type - ]; - - match io::fs::mkdir_recursive(&root.join("target"), io::UserRWX) { - Err(_) => fail!("Couldn't mkdir -p"), - Ok(val) => val - } - - println!("Executing rustc {}", args.as_slice()); - - let mut config = ProcessConfig::new(); - config.stdout = InheritFd(1); - config.stderr = InheritFd(2); - config.program = "rustc"; - config.args = args.as_slice(); - - let mut p = try!(Process::configure(config).to_cargo_error(format!("Could not start process: rustc {}", args.as_slice()), 1)); - - let status = p.wait(); - - if status != std::io::process::ExitStatus(0) { - fail!("Failed to execute") - } - - Ok(None) -} - -fn join(path: &Path, part: ~str) -> ~str { - format!("{}", path.join(part).display()) -} diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index 122a3364c..25a5f066e 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -1,116 +1,20 @@ -use semver::Version; +use core::package::NameVer; -#[deriving(Clone,Eq,Show)] +#[deriving(Eq,Clone,Show)] pub struct Dependency { - name: ~str, - version: Vec -} - -#[deriving(Clone,Eq,Show)] -pub struct VersionReq { - parts: Vec -} - -type VersionOrd = (Version, Vec); - -impl VersionReq { - pub fn parse(req: &str) -> VersionReq { - } - - /* - pub fn new(version: Version, comparison: Vec) -> VersionReq { - VersionReq { comparison: comparison, version: version } - } - */ - - pub fn matches(&self, version: &Version) -> bool { - /* - let ordering = compare_versions(&self.version, version); - self.comparison.iter().any(|ord| ordering == *ord) - */ - false - } -} - -fn compare_versions(a: &Version, b: &Version) -> Ordering { - if a == b { - Equal - } else if a.lt(b) { - Less - } else { - Greater - } + name: NameVer } impl Dependency { pub fn new(name: &str) -> Dependency { - Dependency { name: name.to_owned(), version: Vec::new() } + Dependency { name: NameVer::new(name.to_owned(), "1.0.0") } } - pub fn get_name<'a>(&'a self) -> &'a str { - self.name.as_slice() + pub fn with_name_and_version(name: &str, version: &str) -> Dependency { + Dependency { name: NameVer::new(name, version) } } -} - -#[cfg(test)] -mod tests { - use super::VersionReq; - use semver; - use semver::Version; - use hamcrest::{ - assert_that, - Matcher, - MatchResult, - SelfDescribing - }; - trait VersionReqExt { - pub fn greater_than(version: Version) -> VersionReq { - VersionReq::new(version, vec!(Greater)) - } - - pub fn equal_to(version: Version) -> VersionReq { - VersionReq::new(version, vec!(Equal)) - } - } - - impl VersionReqExt for VersionReq {} - - #[test] - fn test_req_matches() { - let req = VersionReq::new(semver::parse("2.0.0").unwrap(), vec!(Equal)); - //let req = greater_than(semver::parse("2.0.0").unwrap()); - - assert_that(req, version_match("2.0.0")); - } - - struct VersionMatch { - version: ~str, - } - - impl SelfDescribing for VersionMatch { - fn describe(&self) -> ~str { - format!("Requirement to match {}", self.version) - } - } - - impl Matcher for VersionMatch { - fn matches(&self, actual: VersionReq) -> MatchResult { - match semver::parse(self.version) { - None => Err(~"was not a valid semver version"), - Some(ref version) => { - if actual.matches(version) { - Ok(()) - } else { - Err(format!("{} did not match {}", version, actual)) - } - } - } - } - } - - fn version_match(str: &str) -> ~VersionMatch { - ~VersionMatch { version: str.to_owned() } + pub fn get_name<'a>(&'a self) -> &'a str { + self.name.get_name() } - } diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index a91ca30d9..6cca1442d 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -1,3 +1,4 @@ +use core::package::NameVer; /* * TODO: Make all struct fields private @@ -8,7 +9,18 @@ pub struct Manifest { pub project: ~Project, pub root: ~str, pub lib: ~[LibTarget], - pub bin: ~[ExecTarget] + pub bin: ~[ExecTarget], + pub dependencies: Vec +} + +impl Manifest { + pub fn get_name_ver(&self) -> NameVer { + NameVer::new(self.project.name.as_slice(), self.project.version.as_slice()) + } + + pub fn get_path<'a>(&'a self) -> Path { + Path::new(self.root.as_slice()) + } } #[deriving(Decodable,Encodable,Eq,Clone,Ord)] diff --git a/src/cargo/core/mod.rs b/src/cargo/core/mod.rs index 56b552a66..e152908a5 100644 --- a/src/cargo/core/mod.rs +++ b/src/cargo/core/mod.rs @@ -1,19 +1,25 @@ - -pub use self::dependency::Dependency; pub use self::registry::{ - Registry, - MemRegistry}; + Registry, + MemRegistry +}; pub use self::manifest::{ - Manifest, - Project, - LibTarget, - ExecTarget}; + Manifest, + Project, + LibTarget, + ExecTarget +}; -pub use self::package::Package; +pub use self::package::{ + Package, + NameVer +}; + +pub use self::dependency::Dependency; -mod dependency; +pub mod source; +pub mod package; +pub mod dependency; mod manifest; -mod package; mod registry; mod resolver; diff --git a/src/cargo/core/package.rs b/src/cargo/core/package.rs index 0b9e97fa8..7ffd8bfcc 100644 --- a/src/cargo/core/package.rs +++ b/src/cargo/core/package.rs @@ -1,5 +1,38 @@ use std::vec::Vec; +use semver; +use semver::{Version,parse}; use core; +use serialize::{Encodable,Encoder,Decodable,Decoder}; + +#[deriving(Clone,Eq,Show,Ord)] +pub struct NameVer { + name: ~str, + version: Version +} + +impl NameVer { + pub fn new(name: &str, version: &str) -> NameVer { + println!("version: {}", version); + NameVer { name: name.to_owned(), version: semver::parse(version.to_owned()).unwrap() } + } + + pub fn get_name<'a>(&'a self) -> &'a str { + self.name.as_slice() + } +} + +impl> Decodable for NameVer { + fn decode(d: &mut D) -> Result { + let vector: Vec<~str> = try!(Decodable::decode(d)); + Ok(NameVer { name: vector.get(0).clone(), version: parse(vector.get(1).clone()).unwrap() }) + } +} + +impl> Encodable for NameVer { + fn encode(&self, e: &mut S) -> Result<(), E> { + (vec!(self.name.clone(), self.version.to_str())).encode(e) + } +} /** * Represents a rust library internally to cargo. This will things like where diff --git a/src/cargo/core/source.rs b/src/cargo/core/source.rs new file mode 100644 index 000000000..e5c4fe267 --- /dev/null +++ b/src/cargo/core/source.rs @@ -0,0 +1,48 @@ +use core::package::NameVer; +use CargoResult; + +pub struct PackagePath { + name: NameVer, + path: Path +} + +impl PackagePath { + pub fn new(name: NameVer, path: Path) -> PackagePath { + PackagePath { name: name, path: path } + } +} + +/** + * A Source finds and downloads remote packages based on names and + * versions. + */ +pub trait Source { + /** + * The update method performs any network operations required to + * get the entire list of all names, versions and dependencies of + * packages managed by the Source. + */ + fn update(&self) -> CargoResult<()>; + + /** + * The list method lists all names, versions and dependencies of + * packages managed by the source. It assumes that `update` has + * already been called and no additional network operations are + * required. + */ + fn list(&self) -> CargoResult>; + + /** + * The download method fetches the full package for each name and + * version specified. + */ + fn download(&self, packages: Vec) -> CargoResult<()>; + + /** + * The get method returns the Path of each specified package on the + * local file system. It assumes that `download` was already called, + * and that the packages are already locally available on the file + * system. + */ + fn get(&self, packages: Vec) -> CargoResult>; +} diff --git a/src/cargo/mod.rs b/src/cargo/mod.rs index 57947b706..59c284bc8 100644 --- a/src/cargo/mod.rs +++ b/src/cargo/mod.rs @@ -8,6 +8,7 @@ extern crate collections; extern crate hammer; extern crate serialize; extern crate semver; +extern crate toml; #[cfg(test)] extern crate hamcrest; @@ -21,6 +22,9 @@ use hammer::{FlagDecoder,FlagConfig,HammerError}; pub mod core; pub mod util; +pub mod sources; +pub mod ops; + pub type CargoResult = Result; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs new file mode 100644 index 000000000..1da10a9f5 --- /dev/null +++ b/src/cargo/ops/cargo_compile.rs @@ -0,0 +1,82 @@ +/** + * Cargo compile currently does the following steps: + * + * All configurations are already injected as environment variables via the main cargo command + * + * 1. Read the manifest + * 2. Shell out to `cargo-resolve` with a list of dependencies and sources as stdin + * a. Shell out to `--do update` and `--do list` for each source + * b. Resolve dependencies and return a list of name/version/source + * 3. Shell out to `--do download` for each source + * 4. Shell out to `--do get` for each source, and build up the list of paths to pass to rustc -L + * 5. Call `cargo-rustc` with the results of the resolver zipped together with the results of the `get` + * a. Topologically sort the dependencies + * b. Compile each dependency in order, passing in the -L's pointing at each previously compiled dependency + */ + +use std; +use std::vec::Vec; +use serialize::{Decodable}; +use hammer::{FlagDecoder,FlagConfig,FlagConfiguration,HammerError}; +use std::io; +use std::io::BufReader; +use std::io::process::{Process,ProcessExit,ProcessOutput,InheritFd,ProcessConfig}; +use {ToCargoError,CargoResult}; + +#[deriving(Decodable)] +struct Options { + manifest_path: ~str +} + +impl FlagConfig for Options { + fn config(_: Option, c: FlagConfiguration) -> FlagConfiguration { c } +} + +pub fn compile() -> CargoResult<()> { + let options = try!(flags::()); + let manifest_bytes = try!(read_manifest(options.manifest_path).to_cargo_error(~"Could not read manifest", 1)); + + call_rustc(~BufReader::new(manifest_bytes.as_slice())) +} + +fn flags>() -> CargoResult { + let mut decoder = FlagDecoder::new::(std::os::args().tail()); + Decodable::decode(&mut decoder).to_cargo_error(|e: HammerError| e.message, 1) +} + +fn read_manifest(manifest_path: &str) -> CargoResult> { + Ok((try!(exec_with_output("cargo-read-manifest", [~"--manifest-path", manifest_path.to_owned()], None))).output) +} + +fn call_rustc(mut manifest_data: ~Reader:) -> CargoResult<()> { + let data: &mut Reader = manifest_data; + try!(exec_tty("cargo-rustc", [], Some(data))); + Ok(()) +} + +fn exec_with_output(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult { + Ok((try!(exec(program, args, input, |_| {}))).wait_with_output()) +} + +fn exec_tty(program: &str, args: &[~str], input: Option<&mut Reader>) -> CargoResult { + Ok((try!(exec(program, args, input, |config| { + config.stdout = InheritFd(1); + config.stderr = InheritFd(2); + }))).wait()) +} + +fn exec(program: &str, args: &[~str], input: Option<&mut Reader>, configurator: |&mut ProcessConfig|) -> CargoResult { + let mut config = ProcessConfig::new(); + config.program = program; + config.args = args; + configurator(&mut config); + + println!("Executing {} {}", program, args); + + let mut process = try!(Process::configure(config).to_cargo_error(~"Could not configure process", 1)); + + input.map(|mut reader| io::util::copy(&mut reader, process.stdin.get_mut_ref())); + + Ok(process) +} + diff --git a/src/cargo/ops/cargo_read_manifest.rs b/src/cargo/ops/cargo_read_manifest.rs new file mode 100644 index 000000000..d777eae1e --- /dev/null +++ b/src/cargo/ops/cargo_read_manifest.rs @@ -0,0 +1,90 @@ +use toml; +use hammer::FlagConfig; +use serialize::Decoder; +use toml::from_toml; +use {CargoResult,ToCargoError,core}; +use std::path::Path; +use collections::HashMap; +use core::package::NameVer; +use core::dependency::Dependency; + +#[deriving(Decodable,Encodable,Eq,Clone)] +struct SerializedManifest { + project: ~core::Project, + lib: Option<~[SerializedLibTarget]>, + bin: Option<~[SerializedExecTarget]>, + dependencies: HashMap<~str, ~str> +} + +#[deriving(Decodable,Encodable,Eq,Clone)] +pub struct SerializedTarget { + name: ~str, + path: Option<~str> +} + +pub type SerializedLibTarget = SerializedTarget; +pub type SerializedExecTarget = SerializedTarget; + + +#[deriving(Decodable,Eq,Clone,Ord)] +pub struct ReadManifestFlags { + manifest_path: ~str +} + +impl FlagConfig for ReadManifestFlags {} + +pub fn read_manifest(manifest_path: &str) -> CargoResult { + match execute(ReadManifestFlags { manifest_path: manifest_path.to_owned() }) { + Ok(manifest) => Ok(manifest.unwrap()), + Err(e) => Err(e) + } +} + +pub fn execute(flags: ReadManifestFlags) -> CargoResult> { + let manifest_path = flags.manifest_path; + let root = try!(toml::parse_from_file(manifest_path.clone()).to_cargo_error(format!("Couldn't parse Toml file: {}", manifest_path), 1)); + + let toml_manifest = try!(from_toml::(root.clone()).to_cargo_error(|e: toml::Error| format!("Couldn't parse Toml file: {:?}", e), 1)); + + let (lib, bin) = normalize(&toml_manifest.lib, &toml_manifest.bin); + + let SerializedManifest { project, dependencies, .. } = toml_manifest; + + Ok(Some(core::Manifest { + root: try!(Path::new(manifest_path.clone()).dirname_str().to_cargo_error(format!("Could not get dirname from {}", manifest_path), 1)).to_owned(), + project: project, + lib: lib, + bin: bin, + dependencies: dependencies.iter().map(|(k,v)| NameVer::new(k.clone(),v.clone())).collect() + })) +} + +fn normalize(lib: &Option<~[SerializedLibTarget]>, bin: &Option<~[SerializedExecTarget]>) -> (~[core::LibTarget], ~[core::ExecTarget]) { + fn lib_targets(libs: &[SerializedLibTarget]) -> ~[core::LibTarget] { + let l = &libs[0]; + let path = l.path.clone().unwrap_or_else(|| format!("src/{}.rs", l.name)); + ~[core::LibTarget { path: path, name: l.name.clone() }] + } + + fn bin_targets(bins: &[SerializedExecTarget], default: |&SerializedExecTarget| -> ~str) -> ~[core::ExecTarget] { + bins.iter().map(|bin| { + let path = bin.path.clone().unwrap_or_else(|| default(bin)); + core::ExecTarget { path: path, name: bin.name.clone() } + }).collect() + } + + match (lib, bin) { + (&Some(ref libs), &Some(ref bins)) => { + (lib_targets(libs.as_slice()), bin_targets(bins.as_slice(), |bin| format!("src/bin/{}.rs", bin.name))) + }, + (&Some(ref libs), &None) => { + (lib_targets(libs.as_slice()), ~[]) + }, + (&None, &Some(ref bins)) => { + (~[], bin_targets(bins.as_slice(), |bin| format!("src/{}.rs", bin.name))) + }, + (&None, &None) => { + (~[], ~[]) + } + } +} diff --git a/src/cargo/ops/cargo_rustc.rs b/src/cargo/ops/cargo_rustc.rs new file mode 100644 index 000000000..7a6021fe1 --- /dev/null +++ b/src/cargo/ops/cargo_rustc.rs @@ -0,0 +1,60 @@ +use std; +use std::os::args; +use std::io; +use std::io::process::{Process,ProcessConfig,InheritFd}; +use std::path::Path; +use {CargoResult,CargoError,ToCargoError,NoFlags,core}; + +/** + cargo-rustc -- ...args + + Delegate ...args to actual rustc command +*/ + +pub fn execute(_: NoFlags, manifest: core::Manifest) -> CargoResult> { + let core::Manifest { root, lib, bin, .. } = manifest; + + let (crate_type, out_dir) = if lib.len() > 0 { + ( ~"lib", lib[0].path ) + } else if bin.len() > 0 { + ( ~"bin", bin[0].path ) + } else { + return Err(CargoError::new(~"bad manifest, no lib or bin specified", 1)); + }; + + let root = Path::new(root); + let target = join(&root, ~"target"); + + let args = [ + join(&root, out_dir), + ~"--out-dir", target, + ~"--crate-type", crate_type + ]; + + match io::fs::mkdir_recursive(&root.join("target"), io::UserRWX) { + Err(_) => fail!("Couldn't mkdir -p"), + Ok(val) => val + } + + println!("Executing rustc {}", args.as_slice()); + + let mut config = ProcessConfig::new(); + config.stdout = InheritFd(1); + config.stderr = InheritFd(2); + config.program = "rustc"; + config.args = args.as_slice(); + + let mut p = try!(Process::configure(config).to_cargo_error(format!("Could not start process: rustc {}", args.as_slice()), 1)); + + let status = p.wait(); + + if status != std::io::process::ExitStatus(0) { + fail!("Failed to execute") + } + + Ok(None) +} + +fn join(path: &Path, part: ~str) -> ~str { + format!("{}", path.join(part).display()) +} diff --git a/src/cargo/ops/mod.rs b/src/cargo/ops/mod.rs new file mode 100644 index 000000000..93d60da38 --- /dev/null +++ b/src/cargo/ops/mod.rs @@ -0,0 +1,4 @@ +pub mod path_source; +pub mod cargo_compile; +pub mod cargo_read_manifest; +pub mod cargo_rustc; diff --git a/src/cargo/ops/path_source.rs b/src/cargo/ops/path_source.rs new file mode 100644 index 000000000..6654c0b42 --- /dev/null +++ b/src/cargo/ops/path_source.rs @@ -0,0 +1 @@ +struct PathSourceOp; diff --git a/src/cargo/sources/mod.rs b/src/cargo/sources/mod.rs new file mode 100644 index 000000000..1fb8cc55c --- /dev/null +++ b/src/cargo/sources/mod.rs @@ -0,0 +1 @@ +mod path; diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs new file mode 100644 index 000000000..40ef4f21d --- /dev/null +++ b/src/cargo/sources/path.rs @@ -0,0 +1,49 @@ +use core::source::{Source,PackagePath}; +use core::package::NameVer; +use CargoResult; +use ops::cargo_read_manifest::read_manifest; + +struct PathSource { + paths: Vec +} + +impl PathSource { + pub fn new(paths: Vec) -> PathSource { + PathSource { paths: paths } + } + + fn map(&self, callback: |&Path| -> CargoResult) -> CargoResult> { + let mut ret = Vec::with_capacity(self.paths.len()); + + for path in self.paths.iter() { + ret.push(try!(callback(path))); + } + + Ok(ret) + } +} + +impl Source for PathSource { + fn update(&self) -> CargoResult<()> { Ok(()) } + + fn list(&self) -> CargoResult> { + self.map(|path| { + let manifest = try!(read_manifest(path.as_str().unwrap())); + Ok(manifest.get_name_ver()) + }) + } + + fn download(&self, name_ver: Vec) -> CargoResult<()>{ + Ok(()) + } + + fn get(&self, packages: Vec) -> CargoResult> { + self.map(|path| { + let manifest = try!(read_manifest(path.as_str().unwrap())); + let name_ver = manifest.get_name_ver(); + let path = manifest.get_path(); + + Ok(PackagePath::new(name_ver, path)) + }) + } +}